#include <graphics.h>  
#include <conio.h>
#include <stdio.h>
#include <mmsystem.h>//包含多媒体设备接口文件
#include <math.h>
#include <time.h>
#include "EasyXPng.h"
#include <vector>
using namespace std;
#pragma comment(lib,"winmm.lib")
using namespace std;

#define B_SIZE 20 // 方块大小
#define WIN_WIDTH 720//窗口宽度
#define WIN_LENGTH 720//窗口高度
#define row (WIN_WIDTH/B_SIZE)//行
#define col (WIN_LENGTH /B_SIZE)//列


enum PlayerStatus // 枚举类型，游戏角色所有的可能状态
{
	standleft,standright,standup,standlow,runup,runlow,runleft,runright,die
};

void readRecordFile();  //读取游戏数据文件存档
void writeRecordFile();  //存储游戏数据文件存档
void welcome();//开始界面
void startup();//初始化函数
void show();//绘制函数
void update();
void storeHighlevel(int highlevel);//记录最高分函数
void recordhighlevel();//最高分整体函数
void getHighlevel();//获取最高分函数
void update1();
void update2();
void PlayMusicOnce(TCHAR fileName[80]);//播放音乐哈桑农户
void readRecordFile();//读取游戏数据文件存档
void writeRecordFile();  //存储游戏数据文件存档
void pauseMenu();//暂停界面


char moveDirection;//定义吃豆人的移动方向
int i,j,n,m;
int isFailure = 0;
int sum = 0;   
int xx[5][2];/*判断敌人方向用的结构体*/
int player_x,player_y;
int highlevel = 0; //存储最高分
int life;//定义吃豆人的生命值，生命值为零相当于游戏失败
int chiledou=0;//定义吃豆人是否迟到了加命星星
int issuccessful=0;//定义游戏是否成功
int gameStatus = 0;// 游戏状态，0为初始菜单界面，1为正常游戏，2为结束游戏状态，3为游戏暂停
int p;
int guanqia=1;//定义关卡





enum Element
{
	w,c,e
};
Element map[row][col];//在实际调用中改变的地图
Element maps[row][col]=  
{
{w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w},
{w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w},
{w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w},
{w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w},
{w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w},
{w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w},
{w,w,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,w,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,w,w},
{w,w,e,e,c,e,e,e,e,c,e,e,e,c,e,e,c,e,w,e,e,c,e,e,e,c,e,e,e,c,e,e,e,e,w,w},
{w,w,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,w,e,e,e,e,e,e,e,e,e,e,e,e,e,c,e,w,w},
{w,w,e,e,e,w,w,w,e,c,e,w,w,w,w,e,c,e,w,e,e,e,w,w,w,w,e,c,e,w,w,e,e,e,w,w},
{w,w,e,c,e,w,w,w,e,e,e,w,w,w,w,e,e,e,w,e,c,e,w,w,w,w,e,e,e,w,w,e,c,e,w,w},
{w,w,e,e,e,w,w,w,e,c,e,w,w,w,w,e,c,e,w,e,e,e,w,w,w,w,e,c,e,w,w,e,e,e,w,w},
{w,w,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,w,w},
{w,w,e,e,c,e,c,e,e,c,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,c,e,e,e,c,e,w,w},
{w,w,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,w,w},
{w,w,e,c,e,w,w,w,e,c,e,e,e,c,e,e,c,e,e,e,c,e,e,e,c,e,e,c,e,w,w,e,c,e,w,w},
{w,w,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,w,w},
{w,w,e,c,e,w,w,w,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,w,w,e,c,e,w,w},
{w,w,e,e,e,e,e,e,e,e,e,e,w,w,w,e,e,e,e,e,e,e,w,w,w,e,e,e,e,e,e,e,e,e,w,w},
{w,w,w,w,w,w,w,w,e,c,e,e,w,e,e,e,e,e,e,e,e,e,e,e,w,e,e,c,e,w,w,w,w,w,w,w},
{w,w,w,w,w,w,w,w,e,e,e,e,w,e,e,e,e,c,c,c,e,e,e,e,w,e,e,e,e,w,w,w,w,w,w,w},
{w,w,w,w,w,w,w,w,e,c,e,e,w,w,w,w,w,w,w,w,w,w,w,w,w,e,e,e,e,w,w,w,w,w,w,w},
{w,w,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,w,w},
{w,w,e,e,c,e,c,e,e,e,e,c,e,e,e,e,e,e,e,e,e,e,e,e,e,c,e,c,e,e,c,e,e,e,w,w},
{w,w,e,e,e,e,e,e,e,e,e,e,e,e,e,e,c,e,e,e,c,e,e,e,e,e,e,e,e,e,e,e,e,e,w,w},
{w,w,e,e,e,w,w,w,e,c,e,w,w,w,w,e,e,e,w,e,e,e,w,w,w,w,e,e,e,w,w,e,c,e,w,w},
{w,w,e,c,e,w,w,w,e,e,e,w,w,w,w,e,c,e,w,e,c,e,w,w,w,w,e,e,e,w,w,e,e,e,w,w},
{w,w,e,e,e,w,w,w,e,e,e,w,w,w,w,e,e,e,w,e,e,e,w,w,w,w,e,c,e,w,w,e,c,e,w,w},
{w,w,e,e,c,e,c,e,e,e,e,e,e,c,e,e,c,e,e,e,e,e,c,e,e,e,e,e,e,e,c,e,e,e,w,w},
{w,w,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,w,w},
{w,w,e,c,e,w,w,w,e,c,e,w,e,c,e,e,w,w,w,w,w,e,e,c,e,w,e,c,e,w,w,e,c,e,w,w},
{w,w,e,e,e,e,e,e,e,e,e,w,e,e,e,e,e,e,e,e,e,e,e,e,e,w,e,e,e,e,e,e,e,e,w,w},
{w,w,e,e,e,e,e,e,e,e,e,w,e,e,e,e,e,e,e,e,e,e,e,e,e,w,e,e,e,e,e,e,e,e,w,w},
{w,w,e,c,e,e,e,e,e,c,e,w,e,c,e,e,e,e,e,e,e,e,e,c,e,w,e,c,e,e,e,e,c,e,w,w},
{w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w},
{w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w}};//地图的大致框架



void PlayMusicOnce(TCHAR fileName[80]) // 播放一次音乐函数
{
	TCHAR cmdString1[50];
	_stprintf(cmdString1, _T("open %s alias tmpmusic"), fileName);	// 生成命令字符串
	mciSendString(_T("close tmpmusic"), NULL, 0, NULL); // 先把前面一次的音乐关闭
	mciSendString(cmdString1, NULL, 0, NULL); // 打开音乐
	mciSendString(_T("play tmpmusic"), NULL, 0, NULL); // 仅播放一次	
}
IMAGE im_show; //吃豆人当前展现的图片
IMAGE im_enemy1;  // 最强的敌人图像
IMAGE im_xinxin;//星星的图像
IMAGE bk;//背景图片
int sign[4]={0,0,0,0};//为确保每个普通敌人在撞到墙后才换方向
class Magicalbean // 星星类
{
public:
	int x,y; // 星星坐标
	void initialize() // 初始化
	{
		x=18;
		y=32;
		
	}
};
Magicalbean magicalbean;

class Enemy  // 敌人类
{
public:
	int i;//最强敌人的坐标
	int j;
	int vi;//最强地热的速度
	int vj;
	
	int level; // 玩家玩到第几关
	int lastlevel; // 上一次玩到第几关
	
	struct location//与普通敌人位置有关
	{
		int x;
		int y;

	};
	location enemy[6];
	IMAGE im_enemy[6];  // 普通敌人图像
	int x,y; // 用来刻画敌人的中心坐标
	float enemy_width,enemy_height; // 敌人图像的宽度、高度
	float width,height;
	int x_min,x_max; // 敌人移动的x坐标最大值、最小值
	int vx1 ; // 敌人在x方向的移动速度
	void biaoshi()
	{
		level=1;
	}


	void initialize() // 初始化
	{
		i=10;//最强敌人初坐标
	    j=8;
		int x_min=WIN_WIDTH,x_max=0; // 敌人移动的x坐标最大值、最小值
	     int vx=1 ; // 敌人在x方向的移动速度
		loadimage(&im_enemy1, _T("enemy1.jpg.png")); // 导入最强敌人图片
		loadimage(&im_enemy[1], _T("敌人2.jpg-1.png")); // 导入普通敌人图片
		loadimage(&im_enemy[2], _T("敌人3.jpg-1.png")); // 导入普通敌人图片
		loadimage(&im_enemy[3], _T("敌人4.jpg-1.png")); // 导入普通敌人图片
		loadimage(&im_enemy[4], _T("敌人4.jpg-1.png")); // 导入普通敌人图片
		loadimage(&im_enemy[5], _T("敌人3.jpg-1.png")); // 导入普通敌人图片
		enemy_width = im_enemy1.getwidth(); // 获得图像的宽、高
		enemy_height = im_enemy1.getheight();
		width = im_enemy[3].getwidth(); // 获得图像的宽、高
		height = im_enemy[3].getheight();
		width = im_enemy[1].getwidth(); // 获得图像的宽、高
		height = im_enemy[1].getheight();
		width = im_enemy[2].getwidth(); // 获得图像的宽、高
		height = im_enemy[2].getheight();
		
		//初始化各个关卡各个普通敌人的坐标
		if (level==2)
		{
			enemy[1].x=16;
			enemy[1].y=13;
			
		}
		if (level==3)
		{
			enemy[1].x=16;
			enemy[1].y=13;
			enemy[2].x=7;
			enemy[2].y=8;

		}
		if (level==4)
		{
			enemy[1].x=16;
			enemy[1].y=13;
			enemy[2].x=18;
			enemy[2].y=8;
			enemy[3].x=15;
			enemy[3].y=20;

		}

		if (level==5)
		{
			enemy[1].x=16;
			enemy[1].y=13;
			enemy[2].x=18;
			enemy[2].y=8;
			enemy[3].x=15;
			enemy[3].y=20;
			enemy[4].x=32;
			enemy[4].y=30;

		}

		if (level==6)
		{
			enemy[1].x=16;
			enemy[1].y=13;
			enemy[2].x=18;
			enemy[2].y=8;
			enemy[3].x=15;
			enemy[3].y=20;
			enemy[4].x=32;
			enemy[4].y=30;
			enemy[5].x=6;
			enemy[5].y=31;

		}


	}

	void draw1()// 最强的敌人的绘制
	{
		putimagePng(i* B_SIZE,j* B_SIZE,&im_enemy1); 
	}

	void draw2()// 普通敌人的绘制	
	{

		for (p=1;p<=level-1;p++)
		{
        putimagePng(enemy[p].x*B_SIZE,enemy[p].y*B_SIZE,&im_enemy[p]); 
		}
		//}
	}
	void update()  // 普通敌人随机方向的移动
	{
		
		int loop;
		
        for(p=1;p<=level-1;p++) 
		{
        if(player_x==enemy[p].x&&(enemy[p].y+1)==player_y)
			    enemy[p].y++;
		else if(player_x==enemy[p].x&&(enemy[p].y-1)==player_y)
				enemy[p].y--;
		else if(player_y==enemy[p].y&&(enemy[p].x+1)==player_x)
				enemy[p].x++;
		else if(player_y==enemy[p].y&&(enemy[p].x-1)==player_x)/*只要控制者在身边就立即靠上去*/
				enemy[p].x--; 
		else 
		{ 
			/*这里的方向采取随机赋值,通过sign【4】使得各个敌人直到碰到墙才换方向*/ 
loop:
			{
				if(sign[p]==0)
				xx[p][0]=rand()%4+1;
			}
	
		if(xx[p][0]==1)/*四个方向*/ 
		{ 
			sign[p]=1;
			enemy[p].x--;
		if(map[enemy[p].y][enemy[p].x]==w)/*如果碰墙壁的话就回到原来的地方等待随机的方向*/
			{
				sign[p]=0;
				enemy[p].x++;
			    goto loop; //切换方向
		     } 
		}

		else if(xx[p][0]==2) 
		{ 
				sign[p]=1;
				enemy[p].x++;
				if(map[enemy[p].y][enemy[p].x]==w)
				{
					sign[p]=0;
					enemy[p].x--;
			        goto loop;
			     }
		}
		else if(xx[p][0]==3) 
		{ 
				sign[p]=1;
				enemy[p].y++;
			if(map[enemy[p].y][enemy[p].x]==w)
			{
				sign[p]=0;
				enemy[p].y--;
			    goto loop;
			}
		}
		else if(xx[p][0]==4) 
		{
				sign[p]=1;
				enemy[p].y--;
			if(map[enemy[p].y][enemy[p].x]==w)
		    {
			   sign[p]=0;
			   enemy[p].y++;
			   goto loop; 
		     }
		}
		}
		}
		
	}
	int isCollideEnemy(int p) // 判断吃豆人是否和普通敌人相撞，如果是返回1，否则返回0
	{
		
		float distance_x = abs(player_x - enemy[p].x);
		float distance_y = abs(player_y - enemy[p].y);
		if ( distance_x < 0.4*B_SIZE/78 && distance_y < 0.4*B_SIZE/78 )
			return 1;
		else
			return 0;
		
	}
};
Enemy enemy;

class Player  // 玩家控制的游戏角色类
{
public:
	
	IMAGE im_standright; // 向右站立图像
	IMAGE im_standleft; // 向左站立图像
	IMAGE im_standup; // 向上站立图像
	IMAGE im_standlow; // 向下站立图像
	vector <IMAGE> ims_runright; // 向右奔跑的图像序列
	vector <IMAGE> ims_runleft; // 向左奔跑的图像序列
	vector <IMAGE> ims_runup; // 向上奔跑的图像序列
	vector <IMAGE> ims_runlow;  // 向下奔跑的图像序列
	int animId;  // 用于循环动画播放的id
	PlayerStatus playerStatus; // 当前的状态
	

	float width,height; // 图片的宽度、高度

	void draw()// 显示相关信息	
	{
		// 游戏中显示角色，角色不动，地面、背景相对运动
		putimagePng(player_x,player_y,&im_show); 
	}
	void initialize() // 初始化
	{
		ims_runleft.clear(); // 先清空掉vector
		ims_runright.clear();
		loadimage(&im_standright, _T("向右1.jpg-1.png")); // 导入向右站立图片

		playerStatus = standright; // 初始为向右站立的游戏状态
		im_show = im_standright;  // 初始显示向右站立的图片
		width = im_standright.getwidth(); // 获得图像的宽、高，所有动画图片大小一样
		height = im_standright.getheight();

		TCHAR filename[80];		
		for (int i=1;i<=4;i++) // 把向右奔跑的八张图片对象添加到ims_runright中
		{
			_stprintf(filename, _T("向右%d.jpg-1.png"),i);	
			IMAGE im;
			loadimage(&im,filename);
			ims_runright.push_back(im);
		}
		for (int i=1;i<=4;i++) // 把向左奔跑的八张图片对象添加到ims_runleftt中
		{
			_stprintf(filename, _T("向左%d.jpg-1.png"),i);	
			IMAGE im;
			loadimage(&im,filename);
			ims_runleft.push_back(im);
		}
		for (int i=1;i<=4;i++) // 把向上奔跑的八张图片对象添加到ims_runup中
		{
			_stprintf(filename, _T("向上%d.jpg-1.png"),i);	
			IMAGE im;
			loadimage(&im,filename);
			ims_runup.push_back(im);
		}
		for (int i=1;i<=4;i++) // 把向下奔跑的八张图片对象添加到ims_runlow中
		{
			_stprintf(filename, _T("向下%d.jpg-1.png"),i);	
			IMAGE im;
			loadimage(&im,filename);
			ims_runlow.push_back(im);
		}

		animId = 0; // 动画id开始设为0

		updateXY(17,19); // 开始将角色放在需要的位置
	
	}
	void updateXY(int mx,int my) // 根据输入，更新玩家坐标
	{
		player_x= mx;
		player_y= my;
	}
	void runRight() // 游戏角色向右奔跑
	{
		
		animId++; // 动画图片开始切换
		if (animId>=ims_runright.size()) // 循环切换
		animId = 0;
		im_show = ims_runright[animId];
	}
	void runLeft() // 游戏角色向左奔跑
	{
		
		animId++; // 动画图片开始切换
		if (animId>=ims_runleft.size()) // 循环切换
		animId = 0;
		im_show = ims_runleft[animId];
	}
	void runLow() // 游戏角色向下奔跑
	{
		
		animId++; // 动画图片开始切换
		if (animId>=ims_runlow.size()) // 循环切换
		animId = 0;
		im_show = ims_runlow[animId];
	}
	void runUp() // 游戏角色向上奔跑
	{
		animId++; // 动画图片开始切换
		if (animId>=ims_runup.size()) // 循环切换
		animId = 0;
		im_show = ims_runup[animId];
	}
	
};

Player player; 
void welcome()
{
	loadimage(&bk,_T("welcomelast.jpg"),WIN_WIDTH,WIN_LENGTH);
	putimage(0,0,&bk);
	mciSendString(_T("open./images/beginmusic.mp3"),0,0,0);
	mciSendString(_T("play beginmusic.mp3 repeat"),0,0,0);//循环播放音乐
	setbkmode(TRANSPARENT);
	settextcolor(BLUE);
	settextstyle(52,0, _T("华文彩云"));
	 outtextxy(WIN_WIDTH*0.37, WIN_LENGTH*0.25, "1 新游戏");
	 outtextxy(WIN_WIDTH*0.3, WIN_LENGTH*0.35, "2 读取游戏存档");
	 outtextxy(WIN_WIDTH*0.39,  WIN_LENGTH*0.45, "3 退出");
	 outtextxy(WIN_WIDTH*0.30, WIN_LENGTH*0.55, "ESC键暂停游戏");
	 FlushBatchDraw();
	char input;
	if(kbhit())  // 判断是否有输入
	{
		input = getch();  // 根据用户的不同输入来移动，不必输入回车
		if (input == '1') 
			gameStatus = 1;
		else if (input == '2')
		{
			readRecordFile();
			gameStatus = 1;
		}
		else if (input == '3')
		{
			gameStatus = 2;
			exit(0);
		}
	
	}
}
void pauseMenu() // 游戏暂停后菜单界面，一般按ESC键后启动该界面
{
	putimage(0,0,&bk);	// 显示背景
	setbkmode(TRANSPARENT);
	settextcolor(BLUE);
	settextstyle(52,0, _T("华文彩云"));
	outtextxy(WIN_WIDTH*0.37, WIN_LENGTH*0.25, "1 继续游戏");
	outtextxy(WIN_WIDTH*0.3, WIN_LENGTH*0.35, "2 保存档案");
	outtextxy(WIN_WIDTH*0.39, WIN_LENGTH*0.45, "3 退出");
	outtextxy(WIN_WIDTH*0.30, WIN_LENGTH*0.55, "ESC键暂停游戏");

	FlushBatchDraw();
	Sleep(2);
	
	char input;
	if(kbhit())  // 判断是否有输入
	{
		input = getch();  // 根据用户的不同输入来移动，不必输入回车
		if (input == '1') 
			gameStatus = 1;
		else if (input == '2')
		{
			writeRecordFile();
			gameStatus = 1;
		}
		else if (input == '3')
		{
			gameStatus = 2;
			exit(0);
		}
	}
}

void readRecordFile()  //读取游戏数据文件存档
{
	FILE *fp;
	fp = fopen(".\\gameRecord.txt","r");
	
	for(i=0;i<row;i++)
	  for(j=0;j<col;j++)
	  {
	fscanf(fp,"%d ",&map[i][j]);
	  }
	 
	 fscanf(fp,"%d %d %d %d %d %d %d %d %d ",&enemy.level,&player_x,&player_y,&sum,&issuccessful,&chiledou,&life,&enemy.j,&enemy.i);
	
	for (i=1;i<=enemy.level-1;i++)
	  {
		  fscanf(fp,"%d %d ",&enemy.enemy[i].x,&enemy.enemy[i].y);

	  }
	
	 fclose(fp);
}


void writeRecordFile()  //存储游戏数据文件存档
{
	FILE *fp;
	fp = fopen(".\\gameRecord.txt","w");
	
	for(i=0;i<row;i++)
	  for(j=0;j<col;j++)
	  {
	fprintf(fp,"%d ",map[i][j]);
	  }
	
	  fprintf(fp,"%d %d %d %d %d %d %d %d %d ",enemy.level,player_x,player_y,sum,issuccessful,chiledou,life,enemy.j,enemy.i);


	  for (i=1;i<=enemy.level-1;i++)
	  {
		  fprintf(fp,"%d %d ",enemy.enemy[i].x,enemy.enemy[i].y);

	  }
	 fclose(fp);

}


void recordhighlevel()
{
	 getHighlevel();
    //获取历史最高分
   
	 if (enemy.level>highlevel)
	 {
    highlevel =enemy.level;
	
	 }
    //存入当前最高分
	 storeHighlevel(highlevel);
    

}
//获取最高分函数：getHighScore()：
void getHighlevel()
{
    FILE *fp1 ;   //文件指针，指向成功打开的文件
    //打开文件，以只读的方式r
   
	 fp1 = fopen(".\\highlevel1.txt","r");
    //如果文件不存在，打开文件，以写入的方式w

    if (fp1 == NULL)
    {
        fp1 = fopen(".\\highlevel1.txt","w");
        fprintf(fp1, "%d", highlevel);
    }   
        fscanf(fp1, "%d", &highlevel);

    //关闭文件
    fclose(fp1);
}
//存入当前最高分函数：storeHighScore()：
void storeHighlevel(int highlevel)
{
    FILE * fp1 ;
    fp1 = fopen(".\\highlevel1.txt","w");
    fprintf(fp1, "%d", highlevel);
    fclose(fp1);
}



void startup()
{
	if (guanqia)
	enemy.biaoshi();
	isFailure = 0;
	issuccessful=0;
	life=1;
	sum=0;
	if (enemy.level==1)
	chiledou=0;
	
	loadimage(&im_xinxin, _T("星星.png")); // 导入星星图片

	player.initialize(); 
	enemy.initialize() ; 
	magicalbean.initialize() ; 
	for (i=0;i<row;i++)
		for (j=0;j<col;j++)
			map[i][j] = maps[i][j];//保留最初地图
	setbkcolor(RGB(255, 153, 187)); // 灰色背景
	BeginBatchDraw(); // 开始批量绘图
	while (gameStatus==0)
	welcome(); // 初始菜单界面
	
}
void show()
{
	cleardevice(); // 以背景颜色清空屏幕
	
	while (gameStatus==3)
	pauseMenu(); // 游戏暂停后菜单界面，一般按ESC键后启动该界面
	cleardevice(); 
	
	for (i=0;i<row;i++)
	{
		for (j=0;j<col;j++)
		{
			if (map[i][j]==e) // empty 元素是空白区域
			{
				setfillcolor(WHITE);// 绘制地面
				setlinecolor(RGB(255,153,187));
				fillrectangle(j*B_SIZE,i*B_SIZE,(j+1)*B_SIZE,(i+1)*B_SIZE);
			}
			else if (map[i][j]==w)  // wall 元素是墙
			{
				setfillcolor(BLACK);// 绘制地面
				
				setlinecolor(RGB(119,255,170));
				fillrectangle(j*B_SIZE,i*B_SIZE,(j+1)*B_SIZE,(i+1)*B_SIZE);
			}
			else if (map[i][j]==c)  // cake 元素是糖
			{
				setfillcolor(YELLOW);
				setlinecolor(YELLOW);
  				fillcircle(j*B_SIZE+B_SIZE/2,i*B_SIZE+B_SIZE/2,7);	
			}
		}
	}

	putimagePng(player_x*B_SIZE,player_y*B_SIZE,&im_show); //绘制吃豆人
	setlinecolor(RGB(244,255,244));
	line(0,0,WIN_LENGTH,0);
	line(0,80,WIN_LENGTH,80);
	recordhighlevel();//调用最高分函数

	if (chiledou==0)//确保星星吃到后消失
	{
	putimagePng(B_SIZE*magicalbean.x,B_SIZE*magicalbean.y,&im_xinxin);
	}

	putimagePng(enemy.j* B_SIZE,enemy.i* B_SIZE,&im_enemy1);
	enemy.draw2();

		TCHAR s[20];
		setbkmode(TRANSPARENT); // 文字字体透明
		_stprintf(s, _T("%d"), sum) ;	
		settextcolor(RGB(244,255,244)); // 设定文字颜色
		settextstyle(30, 0, _T("黑体"));//  设定文字大小、样式
		outtextxy(160, 90, s); //  输出文字内容

		TCHAR c[20]; // 字符串
		setbkmode(TRANSPARENT); // 文字透明显示
		_stprintf(c, _T("第 %d 关"), enemy.level); // 生成文字字符串
		settextcolor(RGB(244,255,244));  // 设置文字颜色
		settextstyle(30, 0, _T("黑体")); // 设置文字大小、字体
		outtextxy(310, 690, c); // 输出文字

	
		TCHAR b[20];
		setbkmode(TRANSPARENT); // 文字字体透明
		_stprintf(b, _T("%d"), highlevel) ;	
		settextcolor(RGB(244,255,244)); // 设定文字颜色
		settextstyle(30, 0, _T("黑体"));//  设定文字大小、样式
		outtextxy(680, 90, b); //  输出文字内容

		TCHAR m[20];
		setbkmode(TRANSPARENT); // 文字字体透明
		_stprintf(m, _T("%d"), life) ;	
		settextcolor(RGB(244,250,244)); // 设定文字颜色
		settextstyle(20, 0, _T("黑体"));//  设定文字大小、样式
		outtextxy(300,90, m); //  输出文字内容

		if (isFailure) //  如果游戏失败
	{
		PlayMusicOnce(_T("失败.mp3"));
		setbkmode(TRANSPARENT); // 文字字体透明    
		settextcolor(RGB(255,0,0));// 设定文字颜色
		settextstyle(80, 0, _T("华文彩云")); //  设定文字大小、样式
		outtextxy(240,220,_T("游戏失败")); //  输出文字内容
		
		
	}
		setbkmode(TRANSPARENT); // 文字字体透明
		settextcolor(RGB(244,255,244)); // 设定文字颜色
		settextstyle(20,0, _T("宋体"));//  设定文字大小、样式
		outtextxy(10,90, "CURRENT SCORE"); //  输出文字内容
		outtextxy(480,90, "HIGHEST SCORE");


		setbkmode(TRANSPARENT); // 文字字体透明
		settextcolor(RGB(244,255,244)); // 设定文字颜色
		settextstyle(40, 0, _T("Courier New"));//  设定文字大小、样式
		outtextxy(100,20 , "  EAT ALL THE BEANS!"); //  输出文字内容


		if (issuccessful==1&&enemy.level==6)
			{
		PlayMusicOnce(_T("成功.mp3"));
	    mciSendString(_T("close beginmusic.mp3"),0,0,0);//关闭播放音乐
	    mciSendString(_T("play 成功.mp3 repeat"),0,0,0);//循环播放音乐
		setbkmode(TRANSPARENT); // 文字字体透明    
		settextcolor(RGB(255,0,0));// 设定文字颜色
		settextstyle(80, 0, _T("华文彩云")); //  设定文字大小、样式
		outtextxy(210,300,_T("游戏成功")); //  输出文字内容

	}
	
	    FlushBatchDraw(); // 开始批量绘制
	
}

void update()//跟吃豆人有关的更新函数
{

	        int goal_i = player_y; // 移动的目标位置
			int goal_j = player_x;
			

	if (moveDirection=='a' || moveDirection=='s' || moveDirection=='d' || moveDirection=='w') // 如果是有效按键
	{
			
			if (moveDirection=='a') // 向左
			{
				
				player.runLeft(); 
				goal_j = player_x-1 ; // 目标位置在玩家位置的左边
			
			}
			else if (moveDirection=='d') // 向右
			{
				
				player.runRight(); // 游戏角色向右奔跑
				goal_j = player_x +1 ; // 目标位置在玩家位置的右边 
			   
			}
			else if (moveDirection=='s') // 向下
			{
				
				player.runLow(); 
				goal_i = player_y+1; // 目标位置在玩家位置的下边 
				
			}
			else if (moveDirection=='w') // 向上
			{
				player.runUp(); 
				goal_i = player_y-1; // 目标位置在玩家位置的上边 
				
			}
	}
			if(map[goal_i][goal_j]==e)
			{         
				player_y=goal_i;
				player_x=goal_j;
			}

			if(map[goal_i][goal_j]==c)
			{         
				player_y=goal_i;
				player_x=goal_j;
			}

			if (map[player_y][player_x]==c)
			{
				sum++;			
				i = player_y; 
				j =player_x;
				map[i][j]=e;
			}

			if (chiledou==0)
			{
			if (magicalbean.x==player_x&&magicalbean.y==player_y)
			{
				
				life++;
				chiledou=1;
			}
			}
					

			Sleep(15);
}

void update1()//与敌人的移动有关的更新函数和关卡的变化有关的更新和输入有关的更新
{
	
	if (issuccessful==1&&enemy.level==6)//确保关卡结束，画面停止
		return;

	static int waitIndex = 1; // 静态局部变量，初始化时为1
	waitIndex++; // 每一帧+1
	if (waitIndex==8) // 如果等于10才执行，这样小蛇每隔10帧移动一次
	{
	    int  scalar=1; // 敌人的速度恒定
		if (player_x>enemy.j) // 吃豆人在左边，敌人x方向速度向右
			enemy.vj = scalar;
		else if (player_x<enemy.j) // 吃豆人在右边，敌人x方向速度向左
			enemy.vj = -scalar;
		
		if (player_y>enemy.i) // 吃豆人在敌人下方，敌人y方向速度向下
			enemy.vi = scalar;
		else if (player_y<enemy.i) // 吃豆人在敌人上方，敌人y方向速度向上
			enemy.vi = -scalar;

		if (player_y==enemy.i)//判断敌人与吃豆人是否在同一高度，防止普通敌人反复跳跃
		{
			enemy.vi=0;

		}

		if (player_x==enemy.j)//判断敌人与吃豆人是否在同一宽度，防止普通敌人反复跳跃
		{
			enemy.vj=0;

		}

		if (enemy.j<=0 || enemy.j>=WIN_WIDTH)//判断最强敌人是否撞墙防止其出墙
			enemy.vj = -enemy.vj;
		if (enemy.i<=0 || enemy.i>=WIN_LENGTH)
			enemy.vi = -enemy.vi;

		enemy.j += enemy.vj;//最强敌人的坐标改变
		enemy.i += enemy.vi;

		
			Sleep(5);
			waitIndex=0;

	}

	if (issuccessful==1&&enemy.level!=6) //确保游戏成功进入下一关
	{
		guanqia=0;
		enemy.lastlevel = enemy.level; // 记录lastlevel
		enemy.level ++; // 进入下一关
		Sleep(15);
		startup();
	}
	
	
	static int wait1Index = 1; // 静态局部变量，初始化时为1
		wait1Index++; // 每一帧+1
		if (wait1Index==8) // 如果等于10才执行，这样普通敌人每隔10帧移动一次
		{
			//普通敌人更新位置
	     enemy.update();
		 wait1Index=1;
		}
	
	if(kbhit())  //  如果有按键输入
	{
		char input = getch(); //  获得按键输入
		if (input=='a' || input=='s' || input=='d' || input=='w') // 如果是asdw 
		{
			moveDirection = input;  // 设定移动方向
			update(); // 调用小蛇移动函数
		}
		if (input == 27) // ESC键的ACSII码为27
		{
			gameStatus = 3;
		}
	}
	if(kbhit())  //  如果有按键输入，并且不失败
	{
		char input = getch(); //  获得按键输入
		if (input==' ') // 如果按下空格键，这一关重新开始
			startup(); 
		if (input == 27) // ESC键的ACSII码为27
		{
			gameStatus = 3;
		}
	}
				
}
void update2()//判断是否成功是否失败
{
	
	if (issuccessful==1&&enemy.level==6)//确保关卡结束，画面停止
		return;
	
	static int waitIndex = 1; // 静态局部变量，初始化时为1
	waitIndex++; // 每一帧+1
	if (waitIndex==5) // 如果等于10才执行，这样吃豆人每隔10帧移动一次
	{
		update(); //  调用小蛇移动函数
		waitIndex = 1; // 再变成1
	}
	for (int i=1;i<=enemy.level-1;i++)//判断普通敌人是否与吃豆人发生碰撞
	{
		
		if (enemy.isCollideEnemy(i))
		{
			enemy.enemy[i].x=enemy.enemy[i].x-10;//敌人碰到吃豆人后弹开，防止反复碰撞
			enemy.enemy[i].y=enemy.enemy[i].y-10;
			life--;
		}
	}

	float distance_x = abs(player_x - enemy.j);
		float distance_y = abs(player_y - enemy.i);

		if ( distance_x < 0.4*B_SIZE/15 && distance_y < 0.4*B_SIZE/15 )//判断最强敌人是否与吃豆人发生碰撞
		{
			enemy.j=enemy.j-10;///敌人碰到吃豆人后弹开，防止反复碰撞
			enemy.i=enemy.i-10;
			life--;
		}
	
		if (life==0 )
		{
			PlayMusicOnce(_T("死亡.mp3"));
			enemy.lastlevel = enemy.level;
			Sleep(180);
			startup();
		}

		if(sum==71)
			issuccessful=1;
		
}
int main() // 主函数
{
	initgraph(WIN_WIDTH,WIN_LENGTH);//新开一个窗口
	welcome();
	startup();  // 初始化
	while(1)
	{
		show();		// 绘制
		update1();
		update2();	
	}
	_getch();
	return 0;
}
